package com.andy.blog.admin.service.impl;

import com.andy.blog.admin.dto.ServerDTO;
import com.andy.blog.admin.dto.server.CpuDTO;
import com.andy.blog.admin.dto.server.JvmDTO;
import com.andy.blog.admin.dto.server.MemDTO;
import com.andy.blog.admin.dto.server.SysDTO;
import com.andy.blog.admin.dto.server.SysFileDTO;
import com.andy.blog.admin.service.ServerBusService;
import com.andy.blog.common.utils.DateUtils;
import com.andy.blog.common.utils.SystemInfoUtils;
import com.andy.blog.common.utils.TransformUtils;
import io.vavr.Tuple4;
import io.vavr.Tuple5;
import io.vavr.Tuple6;
import io.vavr.Tuple7;
import org.springframework.stereotype.Service;

import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * Created by andy on 2023-04-15 12:46
 */
@Service("serverBusService")
public class ServerBusServiceImpl implements ServerBusService {


    @Override
    public ServerDTO getServerInfo() {

        ServerDTO serverDTO = new ServerDTO();
        // cpu
        CompletableFuture<Void> cpuFuture = CompletableFuture.runAsync(() -> {
            Tuple6<Integer, String, String, String, String, Long> cpuInfo = SystemInfoUtils.getCpuInfo();
            CpuDTO cpuDTO = CpuDTO.builder().cpuNum(cpuInfo._1).total(cpuInfo._6).sys(cpuInfo._2).used(cpuInfo._3).wait(cpuInfo._4).free(cpuInfo._5).build();
            serverDTO.setCpu(cpuDTO);
        });

        // 内存
        CompletableFuture<Void> memFuture = CompletableFuture.runAsync(() -> {
            Tuple4<String, String, String, String> memInfo = SystemInfoUtils.getMemInfo();
            MemDTO memDTO = MemDTO.builder().total(memInfo._1).used(memInfo._2).free(memInfo._3).usage(memInfo._4).build();
            serverDTO.setMem(memDTO);
        });

        // 服务器信息
        CompletableFuture<Void> sysFuture = CompletableFuture.runAsync(() -> {
            Tuple5<String, String, String, String, String> sysInfo = SystemInfoUtils.getSysInfo();
            SysDTO sysDTO = SysDTO.builder().computerName(sysInfo._4).computerIp(sysInfo._3).userDir(sysInfo._5).osName(sysInfo._1).osArch(sysInfo._2).build();
            serverDTO.setSys(sysDTO);
        });

        // jvm
        CompletableFuture<Void> jvmFuture = CompletableFuture.runAsync(() -> {
            Tuple7<String, String, String, String, String, String, String> jvmInfo = SystemInfoUtils.getJvmInfo();
            JvmDTO jvmDTO = new JvmDTO();
            jvmDTO.setTotal(jvmInfo._1);
            jvmDTO.setMax(jvmInfo._2);
            jvmDTO.setFree(jvmInfo._3);
            jvmDTO.setVersion(jvmInfo._4);
            jvmDTO.setHome(jvmInfo._5);
            jvmDTO.setUsed(jvmInfo._6);
            jvmDTO.setUsage(jvmInfo._7);
            jvmDTO.setInputArgs(ManagementFactory.getRuntimeMXBean().getInputArguments().toString());
            jvmDTO.setRunTime(DateUtils.timeDistance(DateUtils.getCurrentDate(), DateUtils.getServerStartDate()));
            jvmDTO.setStartTime(DateUtils.formatDate(DateUtils.getServerStartDate(), DateUtils.YYYY_MM_DD_HH_MM_SS));
            jvmDTO.setName(ManagementFactory.getRuntimeMXBean().getVmName());
            serverDTO.setJvm(jvmDTO);
        });

        List<SysFileDTO> sysFileDTOS = new ArrayList<>();
        CompletableFuture<Void> fileFuture = CompletableFuture.runAsync(() -> {
            List<Map<String, Object>> sysFileInfo = SystemInfoUtils.getSysFileInfo();
            for (Map<String, Object> map : sysFileInfo) {
                SysFileDTO sysFileDTO = TransformUtils.transMap2Bean(map, SysFileDTO.class);
                sysFileDTOS.add(sysFileDTO);
            }
            serverDTO.setSysFileDTOS(sysFileDTOS);
        });

        CompletableFuture.allOf(cpuFuture, memFuture, sysFuture, jvmFuture, fileFuture).join();

        return serverDTO;
    }
}
